/**************************************************************************
 *                                                                        *
 *         Copyright (c) 2014 by Generalplus Inc.                         *
 *                                                                        *
 *  This software is copyrighted by and is the property of Generalplus    *
 *  Inc. All rights are reserved by Generalplus Inc.                      *
 *  This software may only be used in accordance with the                 *
 *  corresponding license agreement. Any unauthorized use, duplication,   *
 *  distribution, or disclosure of this software is expressly forbidden.  *
 *                                                                        *
 *  This Copyright notice MUST not be removed or modified without prior   *
 *  written consent of Generalplus Technology Co., Ltd.                   *
 *                                                                        *
 *  Generalplus Inc. reserves the right to modify this software           *
 *  without notice.                                                       *
 *                                                                        *
 *  Generalplus Inc.                                                      *
 *  No.19, Industry E. Rd. IV, Hsinchu Science Park                       *
 *  Hsinchu City 30078, Taiwan, R.O.C.                                    *
 *                                                                        *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "drv_l1_sfr.h"
#include "drv_l1_csi.h"
#include "drv_l1_mipi.h"
#include "drv_l1_i2c.h"
#include "drv_l2_sensor.h"
#include "drv_l2_sccb.h"
#include "drv_l2_cdsp.h"
#include "drv_l2_cdsp_config.h"
#include "gplib_print_string.h"

#if (defined _SENSOR_JXH22_CDSP_MIPI) && (_SENSOR_JXH22_CDSP_MIPI == 1)

#include "drv_l2_user_calibration.h"

/**************************************************************************
 *                           C O N S T A N T S                            *
 **************************************************************************/
#define CONFIG_FPGA_TEST				0
#define COLOR_BAR_EN					0
//#define MIPI_ISR_TEST					0
#define MIPI_LANE_NO					MIPI_1_LANE // 1 or 2 lane
#if (MIPI_LANE_NO == MIPI_2_LANE)
#define MIPI_DEV_NO						0			//2Lane only selcet MIPI_0
#else
#define MIPI_DEV_NO						0			//1Lane can 0:MIPI_0 or 1:MIPI_1
#endif

#define	H22_ID							0x60	//0x64,0x68,0x6C
#define H22_WIDTH						1280
#define H22_HEIGHT						720
#define H22_OUT_WIDTH					1280
#define H22_OUT_HEIGHT					720

#ifndef DISABLE
#define DISABLE							0
#endif

#ifndef ENABLE
#define ENABLE							1
#endif

// sccb interface
#define SCCB_GPIO						0
#define SCCB_HW_I2C						1
#define SCCB_MODE						SCCB_HW_I2C


#define H22_30FPS_50HZ_DAY_EV_IDX 			140
#define H22_30FPS_50HZ_NIGHT_EV_IDX			190
#define H22_30FPS_50HZ_EXP_TIME_TOTAL		212
#define H22_30FPS_50HZ_INIT_EV_IDX			((H22_30FPS_50HZ_DAY_EV_IDX + H22_30FPS_50HZ_NIGHT_EV_IDX) >> 1)
#define H22_30FPS_50HZ_MAX_EV_IDX			(H22_30FPS_50HZ_EXP_TIME_TOTAL - 10)


#define H22_30FPS_60HZ_DAY_EV_IDX 			137
#define H22_30FPS_60HZ_NIGHT_EV_IDX			190
#define H22_30FPS_60HZ_EXP_TIME_TOTAL		215
#define H22_30FPS_60HZ_INIT_EV_IDX			((H22_30FPS_60HZ_DAY_EV_IDX + H22_30FPS_60HZ_NIGHT_EV_IDX) >> 1)
#define H22_30FPS_60HZ_MAX_EV_IDX			(H22_30FPS_60HZ_EXP_TIME_TOTAL - 10)


#define H22_24FPS_50HZ_DAY_EV_IDX			138
#define H22_24FPS_50HZ_NIGHT_EV_IDX			194
#define H22_24FPS_50HZ_EXP_TIME_TOTAL		254
#define H22_24FPS_50HZ_INIT_EV_IDX			((H22_24FPS_50HZ_DAY_EV_IDX + H22_24FPS_50HZ_NIGHT_EV_IDX) >> 1)
#define H22_24FPS_50HZ_MAX_EV_IDX			(H22_24FPS_50HZ_EXP_TIME_TOTAL - 10)


#define H22_24FPS_60HZ_DAY_EV_IDX			135
#define H22_24FPS_60HZ_NIGHT_EV_IDX			195
#define H22_24FPS_60HZ_EXP_TIME_TOTAL		255
#define H22_24FPS_60HZ_INIT_EV_IDX			((H22_24FPS_60HZ_DAY_EV_IDX + H22_24FPS_60HZ_NIGHT_EV_IDX) >> 1)
#define H22_24FPS_60HZ_MAX_EV_IDX			(H22_24FPS_60HZ_EXP_TIME_TOTAL - 10)


/**************************************************************************
 *                              M A C R O S                               *
 **************************************************************************/

/**************************************************************************
 *                          D A T A    T Y P E S                          *
 **************************************************************************/
typedef struct regval8_s
{
	INT8U reg_num;
	INT8U value;
} regval8_t;

/**************************************************************************
 *                         G L O B A L    D A T A                         *
 **************************************************************************/
static int ob_cnt = 0;
static int *p_expTime_table;
static sensor_exposure_t 	seInfo;
static int pre_sensor_a_gain, pre_sensor_time;

static INT8U ae_flag = 0;

#if SCCB_MODE == SCCB_GPIO
	sccb_config_t h22_cdsp_mipi_sccb_config = {
		FRONT_SENSOR_GPIO_SCL,		//scl_port
		FRONT_SENSOR_GPIO_DRIVING,	//scl_drv
		FRONT_SENSOR_GPIO_SDA,		//sda_port
		FRONT_SENSOR_GPIO_DRIVING,	//sda_drv
		0,							//pwdn_port
		0,							//pwdn_drv
		0,							//have_pwdn
		8,							//RegBits
		8,							//DataBits
		H22_ID,						//slaveAddr
		0x20000,					//timeout
		100							//clock_rate
	};

	static void *h22_handle;
#elif SCCB_MODE == SCCB_HW_I2C
	#define I2C_DEVICE_NUM 			I2C_1
	static drv_l1_i2c_bus_handle_t h22_handle;
#endif

static mipi_config_t h22_mipi_cfg =
{
	DISABLE,			/* low power, 0:disable, 1:enable */

#if MIPI_LANE_NO == MIPI_1_LANE
	D_PHY_SAMPLE_NEG,	/* byte clock edge, 0:posedge, 1:negedge */
	MIPI_1_LANE,		/* lane */
	GENERATE_PIXEL_CLK, //D_PHY_BYTE_CLK,		/* byte clock source */
#elif MIPI_LANE_NO == MIPI_2_LANE
	D_PHY_SAMPLE_POS,
	MIPI_2_LANE,		/* lane */
	GENERATE_PIXEL_CLK,	/* byte clock source */
#endif

	MIPI_AUTO_DETECT,	/* data mode, 0:auto detect, 1:user define */
	MIPI_RAW10,			/* data type, valid when data mode is 1*/
	MIPI_DATA_TO_CDSP,	/* data type, 1:data[7:0]+2':00 to cdsp, 0: 2'00+data[7:0] to csi */
	0,//NULL,				/* RSD 2 */

	H22_WIDTH,		/* width, 0~0xFFFF */
	H22_HEIGHT,		/* height, 0~0xFFFF */
	4,					/* back porch, 0~0xF */ //If Set 4 have show paper color at left side.u2.20160119
	4,					/* front porch, 0~0xF */
	ENABLE,				/* blanking_line_en, 0:disable, 1:enable */
	0,//NULL,				/* RSD 3 */

	ENABLE,				/* ecc, 0:disable, 1:enable */
	MIPI_ECC_ORDER3,	/* ecc order */
	250,//100,//250,				/* data mask, unit is ns */
	MIPI_CHECK_LP_00//MIPI_CHECK_HS_SEQ	/* check hs sequence or LP00 for clock lane */
};

static const regval8_t h22_reset_table[] =
{
	{ 0x12, 0x80 },
	{ 0xFF, 0xFF },
};

static const regval8_t h22_init_table[] =
{
	{ 0x12, 0x80 },
	{ 0x12, 0x80 },

	//Sleep Mode
	{0x12,0x40},
	//Gain
	{0x0E,0x1D}, //for MCLK=24Mhz, please change to 1C for MCLK=12Mhz
	{0x0F,0x09},
	{0x10,0x1A},
	{0x11,0x80},
	//AEC/AGC
	{0x13,0x01},
	{0x14,0x80},
	{0x16,0xA0},
	{0x17,0x40},
	{0x18,0xD5},
	{0x19,0x00},
	//DVP
	{0x1D,0x00},
	{0x1E,0x1C},
	//Frame
	{0x20,0xDC},
	{0x21,0x05},
	{0x22,0x56},
	{0x23,0x03},
	//Window
	{0x24,0x04},	//enhance +4
	{0x25,0xD6},	//enhance +6//for input 724
	{0x26,0x25},
	{0x27,0xC1},
	{0x28,0x0D},
	{0x29,0x00},
	//Physical
	{0x2C,0x00},
	{0x2D,0x0A},
	{0x2E,0xC2},
	{0x2F,0x20},
	{0x37,0x40},
	{0x38,0x98},
	//MIPI raw10
	{0x67,0x30},//Mipi sleep mode disable
	{0x6c,0x10},//Mipi active
	{0x76,0x40},//word counter low
	{0x77,0x06},//word counter high
	{0x12,0x00},
	#if (SENSOR_FLIP == 1)
	{0x12,0x30},
	#else
	{0x12,0x00},
	#endif
	{0xFF,0xFF}
};



static const int h22_mipi_30fps_exp_time_gain_50Hz[H22_30FPS_50HZ_EXP_TIME_TOTAL][3] =
{ // {time, analog gain, digital gain}
	{8	,(int)(1.00*16), (int)(1.00*64)},	//0
	{9	,(int)(1.00*16), (int)(1.00*64)},
	{9	,(int)(1.00*16), (int)(1.00*64)},
	{9	,(int)(1.00*16), (int)(1.00*64)},
	{10	,(int)(1.00*16), (int)(1.00*64)},
	{10	,(int)(1.00*16), (int)(1.00*64)},
	{10	,(int)(1.00*16), (int)(1.00*64)},
	{11	,(int)(1.00*16), (int)(1.00*64)},
	{11	,(int)(1.00*16), (int)(1.00*64)},
	{11	,(int)(1.00*16), (int)(1.00*64)},
	{12	,(int)(1.00*16), (int)(1.00*64)},   //10
	{12	,(int)(1.00*16), (int)(1.00*64)},
	{13	,(int)(1.00*16), (int)(1.00*64)},
	{13	,(int)(1.00*16), (int)(1.00*64)},
	{13	,(int)(1.00*16), (int)(1.00*64)},
	{14	,(int)(1.00*16), (int)(1.00*64)},
	{14	,(int)(1.00*16), (int)(1.00*64)},
	{15	,(int)(1.00*16), (int)(1.00*64)},
	{15	,(int)(1.00*16), (int)(1.00*64)},
	{16	,(int)(1.00*16), (int)(1.00*64)},
	{17	,(int)(1.00*16), (int)(1.00*64)},   //20
	{17	,(int)(1.00*16), (int)(1.00*64)},
	{18	,(int)(1.00*16), (int)(1.00*64)},
	{18	,(int)(1.00*16), (int)(1.00*64)},
	{19	,(int)(1.00*16), (int)(1.00*64)},
	{20	,(int)(1.00*16), (int)(1.00*64)},
	{20	,(int)(1.00*16), (int)(1.00*64)},
	{21	,(int)(1.00*16), (int)(1.00*64)},
	{22	,(int)(1.00*16), (int)(1.00*64)},
	{23	,(int)(1.00*16), (int)(1.00*64)},
	{23	,(int)(1.00*16), (int)(1.00*64)},   //30
	{24	,(int)(1.00*16), (int)(1.00*64)},
	{25	,(int)(1.00*16), (int)(1.00*64)},
	{26	,(int)(1.00*16), (int)(1.00*64)},
	{27	,(int)(1.00*16), (int)(1.00*64)},
	{28	,(int)(1.00*16), (int)(1.00*64)},
	{29	,(int)(1.00*16), (int)(1.00*64)},
	{30	,(int)(1.00*16), (int)(1.00*64)},
	{31	,(int)(1.00*16), (int)(1.00*64)},
	{32	,(int)(1.00*16), (int)(1.00*64)},
	{33	,(int)(1.00*16), (int)(1.00*64)},   //40
	{34	,(int)(1.00*16), (int)(1.00*64)},
	{36	,(int)(1.00*16), (int)(1.00*64)},
	{37	,(int)(1.00*16), (int)(1.00*64)},
	{38	,(int)(1.00*16), (int)(1.00*64)},
	{39	,(int)(1.00*16), (int)(1.00*64)},
	{41	,(int)(1.00*16), (int)(1.00*64)},
	{42	,(int)(1.00*16), (int)(1.00*64)},
	{44	,(int)(1.00*16), (int)(1.00*64)},
	{45	,(int)(1.00*16), (int)(1.00*64)},
	{47	,(int)(1.00*16), (int)(1.00*64)},   //50
	{49	,(int)(1.00*16), (int)(1.00*64)},
	{50	,(int)(1.00*16), (int)(1.00*64)},
	{52	,(int)(1.00*16), (int)(1.00*64)},
	{54	,(int)(1.00*16), (int)(1.00*64)},
	{56	,(int)(1.00*16), (int)(1.00*64)},
	{58	,(int)(1.00*16), (int)(1.00*64)},
	{60	,(int)(1.00*16), (int)(1.00*64)},
	{62	,(int)(1.00*16), (int)(1.00*64)},
	{64	,(int)(1.00*16), (int)(1.00*64)},
	{66	,(int)(1.00*16), (int)(1.00*64)},   //60
	{69	,(int)(1.00*16), (int)(1.00*64)},
	{71	,(int)(1.00*16), (int)(1.00*64)},
	{74	,(int)(1.00*16), (int)(1.00*64)},
	{76	,(int)(1.00*16), (int)(1.00*64)},
	{79	,(int)(1.00*16), (int)(1.00*64)},
	{82	,(int)(1.00*16), (int)(1.00*64)},
	{84	,(int)(1.00*16), (int)(1.00*64)},
	{87	,(int)(1.00*16), (int)(1.00*64)},
	{91	,(int)(1.00*16), (int)(1.00*64)},
	{94	,(int)(1.00*16), (int)(1.00*64)},   //70
	{97	,(int)(1.00*16), (int)(1.00*64)},
	{100,(int)(1.00*16), (int)(1.00*64)},
	{104,(int)(1.00*16), (int)(1.00*64)},
	{108,(int)(1.00*16), (int)(1.00*64)},
	{111,(int)(1.00*16), (int)(1.00*64)},
	{115,(int)(1.00*16), (int)(1.00*64)},
	{119,(int)(1.00*16), (int)(1.00*64)},
	{124,(int)(1.00*16), (int)(1.00*64)},
	{128,(int)(1.00*16), (int)(1.00*64)},
	{133,(int)(1.00*16), (int)(1.00*64)},   //80
	{137,(int)(1.00*16), (int)(1.00*64)},
	{142,(int)(1.00*16), (int)(1.00*64)},
	{147,(int)(1.00*16), (int)(1.00*64)},
	{152,(int)(1.00*16), (int)(1.00*64)},
	{158,(int)(1.00*16), (int)(1.00*64)},
	{163,(int)(1.00*16), (int)(1.00*64)},
	{169,(int)(1.00*16), (int)(1.00*64)},
	{175,(int)(1.00*16), (int)(1.00*64)},
	{181,(int)(1.00*16), (int)(1.00*64)},
	{187,(int)(1.00*16), (int)(1.00*64)},   //90
	{194,(int)(1.00*16), (int)(1.00*64)},
	{201,(int)(1.00*16), (int)(1.00*64)},
	{208,(int)(1.00*16), (int)(1.00*64)},
	{215,(int)(1.00*16), (int)(1.00*64)},
	{223,(int)(1.00*16), (int)(1.00*64)},
	{231,(int)(1.00*16), (int)(1.00*64)},
	{239,(int)(1.00*16), (int)(1.00*64)},
	{247,(int)(1.00*16), (int)(1.00*64)},
	{256,(int)(1.00 *16),(int)(1.00*64)},
	{256,(int)(1.04 *16),(int)(1.00*64)},  //100
	{256,(int)(1.07 *16),(int)(1.00*64)},
	{256,(int)(1.11 *16),(int)(1.00*64)},
	{256,(int)(1.15 *16),(int)(1.00*64)},
	{256,(int)(1.19 *16),(int)(1.00*64)},
	{256,(int)(1.23 *16),(int)(1.00*64)},
	{256,(int)(1.27 *16),(int)(1.00*64)},
	{256,(int)(1.32 *16),(int)(1.00*64)},
	{256,(int)(1.37 *16),(int)(1.00*64)},
	{256,(int)(1.41 *16),(int)(1.00*64)},
	{256,(int)(1.46 *16),(int)(1.00*64)},  //110
	{256,(int)(1.52 *16),(int)(1.00*64)},
	{256,(int)(1.57 *16),(int)(1.00*64)},
	{256,(int)(1.62 *16),(int)(1.00*64)},
	{256,(int)(1.68 *16),(int)(1.00*64)},
	{256,(int)(1.74 *16),(int)(1.00*64)},
	{256,(int)(1.80 *16),(int)(1.00*64)},
	{256,(int)(1.87 *16),(int)(1.00*64)},
	{256,(int)(1.93 *16),(int)(1.00*64)},
	{512,(int)(1.00 *16),(int)(1.00*64)},
	{512,(int)(1.04 *16),(int)(1.00*64)},  //120
	{512,(int)(1.07 *16),(int)(1.00*64)},
	{512,(int)(1.11 *16),(int)(1.00*64)},
	{512,(int)(1.15 *16),(int)(1.00*64)},
	{512,(int)(1.19 *16),(int)(1.00*64)},
	{512,(int)(1.23 *16),(int)(1.00*64)},
	{512,(int)(1.27 *16),(int)(1.00*64)},
	{512,(int)(1.32 *16),(int)(1.00*64)},
	{512,(int)(1.37 *16),(int)(1.00*64)},
	{512,(int)(1.41 *16),(int)(1.00*64)},
	{512,(int)(1.46 *16),(int)(1.00*64)},  //130
	{512,(int)(1.52 *16),(int)(1.00*64)},
	{512,(int)(1.57 *16),(int)(1.00*64)},
	{512,(int)(1.62 *16),(int)(1.00*64)},
	{512,(int)(1.68 *16),(int)(1.00*64)},
	{512,(int)(1.74 *16),(int)(1.00*64)},
	{512,(int)(1.80 *16),(int)(1.00*64)},
	{512,(int)(1.87 *16),(int)(1.00*64)},
	{512,(int)(1.93 *16),(int)(1.00*64)},
	{768,(int)(1.32 *16),(int)(1.00*64)},
	{768,(int)(1.37 *16),(int)(1.00*64)},  //140
	{768,(int)(1.41 *16),(int)(1.00*64)},
	{768,(int)(1.46 *16),(int)(1.00*64)},
	{768,(int)(1.52 *16),(int)(1.00*64)},
	{768,(int)(1.57 *16),(int)(1.00*64)},
	{768,(int)(1.62 *16),(int)(1.00*64)},
	{768,(int)(1.68 *16),(int)(1.00*64)},
	{768,(int)(1.74 *16),(int)(1.00*64)},
	{768,(int)(1.80 *16),(int)(1.00*64)},
	{768,(int)(1.87 *16),(int)(1.00*64)},
	{768,(int)(1.93 *16),(int)(1.00*64)},  //150
	{768,(int)(2.00 *16),(int)(1.00*64)},
	{768,(int)(2.07 *16),(int)(1.00*64)},
	{768,(int)(2.14 *16),(int)(1.00*64)},
	{768,(int)(2.22 *16),(int)(1.00*64)},
	{768,(int)(2.30 *16),(int)(1.00*64)},
	{768,(int)(2.38 *16),(int)(1.00*64)},
	{768,(int)(2.46 *16),(int)(1.00*64)},
	{768,(int)(2.55 *16),(int)(1.00*64)},
	{768,(int)(2.64 *16),(int)(1.00*64)},
	{768,(int)(2.73 *16),(int)(1.00*64)},  //160
	{768,(int)(2.83 *16),(int)(1.00*64)},
	{768,(int)(2.93 *16),(int)(1.00*64)},
	{768,(int)(3.03 *16),(int)(1.00*64)},
	{768,(int)(3.14 *16),(int)(1.00*64)},
	{768,(int)(3.25 *16),(int)(1.00*64)},
	{768,(int)(3.36 *16),(int)(1.00*64)},
	{768,(int)(3.48 *16),(int)(1.00*64)},
	{768,(int)(3.61 *16),(int)(1.00*64)},
	{768,(int)(3.73 *16),(int)(1.00*64)},
	{768,(int)(3.86 *16),(int)(1.00*64)},  //170
	{768,(int)(4.00 *16),(int)(1.00*64)},
	{768,(int)(4.14 *16),(int)(1.00*64)},
	{768,(int)(4.29 *16),(int)(1.00*64)},
	{768,(int)(4.44 *16),(int)(1.00*64)},
	{768,(int)(4.59 *16),(int)(1.00*64)},
	{768,(int)(4.76 *16),(int)(1.00*64)},
	{768,(int)(4.92 *16),(int)(1.00*64)},
	{768,(int)(5.10 *16),(int)(1.00*64)},
	{768,(int)(5.28 *16),(int)(1.00*64)},
	{768,(int)(5.46 *16),(int)(1.00*64)},  //180
	{768,(int)(5.66 *16),(int)(1.00*64)},
	{768,(int)(5.86 *16),(int)(1.00*64)},
	{768,(int)(6.06 *16),(int)(1.00*64)},
	{768,(int)(6.28 *16),(int)(1.00*64)},
	{768,(int)(6.50 *16),(int)(1.00*64)},
	{768,(int)(6.73 *16),(int)(1.00*64)},
	{768,(int)(6.96 *16),(int)(1.00*64)},
	{768,(int)(7.21 *16),(int)(1.00*64)},
	{768,(int)(7.46 *16),(int)(1.00*64)},
	{768,(int)(7.73 *16),(int)(1.00*64)},  //190
	{768,(int)(8.00 *16),(int)(1.00*64)},
	{768,(int)(8.28 *16),(int)(1.00*64)},
	{768,(int)(8.57 *16),(int)(1.00*64)},
	{768,(int)(8.88 *16),(int)(1.00*64)},
	{768,(int)(9.19 *16),(int)(1.00*64)},
	{768,(int)(9.51 *16),(int)(1.00*64)},
	{768,(int)(9.85 *16),(int)(1.00*64)},
	{768,(int)(10.20*16),(int)(1.00*64)},
	{768,(int)(10.56*16),(int)(1.00*64)},
	{768,(int)(10.93*16),(int)(1.00*64)},  //200
	{768,(int)(11.31*16),(int)(1.00*64)},
	{768,(int)(11.71*16),(int)(1.00*64)},
	{768,(int)(12.13*16),(int)(1.00*64)},
	{768,(int)(12.55*16),(int)(1.00*64)},
	{768,(int)(13.00*16),(int)(1.00*64)},
	{768,(int)(13.45*16),(int)(1.00*64)},
	{768,(int)(13.93*16),(int)(1.00*64)},
	{768,(int)(14.42*16),(int)(1.00*64)},
	{768,(int)(14.93*16),(int)(1.00*64)},
	{768,(int)(15.45*16),(int)(1.00*64)},  //210
	{768,(int)(16.00*16),(int)(1.00*64)},
};

static const  int h22_mipi_30fps_exp_time_gain_60Hz[H22_30FPS_60HZ_EXP_TIME_TOTAL][3] =
{ // {time, analog gain, digital gain}
	{8	,(int)(1.00*16), (int)(1.00*64)},	//0
	{9	,(int)(1.00*16), (int)(1.00*64)},
	{9	,(int)(1.00*16), (int)(1.00*64)},
	{9	,(int)(1.00*16), (int)(1.00*64)},
	{10	,(int)(1.00*16), (int)(1.00*64)},
	{10	,(int)(1.00*16), (int)(1.00*64)},
	{10	,(int)(1.00*16), (int)(1.00*64)},
	{11	,(int)(1.00*16), (int)(1.00*64)},
	{11	,(int)(1.00*16), (int)(1.00*64)},
	{12	,(int)(1.00*16), (int)(1.00*64)},
	{12	,(int)(1.00*16), (int)(1.00*64)},	//10
	{12	,(int)(1.00*16), (int)(1.00*64)},
	{13	,(int)(1.00*16), (int)(1.00*64)},
	{13	,(int)(1.00*16), (int)(1.00*64)},
	{14	,(int)(1.00*16), (int)(1.00*64)},
	{14	,(int)(1.00*16), (int)(1.00*64)},
	{15	,(int)(1.00*16), (int)(1.00*64)},
	{15	,(int)(1.00*16), (int)(1.00*64)},
	{16	,(int)(1.00*16), (int)(1.00*64)},
	{16	,(int)(1.00*16), (int)(1.00*64)},
	{17	,(int)(1.00*16), (int)(1.00*64)},	//20
	{18	,(int)(1.00*16), (int)(1.00*64)},
	{18	,(int)(1.00*16), (int)(1.00*64)},
	{19	,(int)(1.00*16), (int)(1.00*64)},
	{19	,(int)(1.00*16), (int)(1.00*64)},
	{20	,(int)(1.00*16), (int)(1.00*64)},
	{21	,(int)(1.00*16), (int)(1.00*64)},
	{22	,(int)(1.00*16), (int)(1.00*64)},
	{22	,(int)(1.00*16), (int)(1.00*64)},
	{23	,(int)(1.00*16), (int)(1.00*64)},
	{24	,(int)(1.00*16), (int)(1.00*64)},	//30
	{25	,(int)(1.00*16), (int)(1.00*64)},
	{26	,(int)(1.00*16), (int)(1.00*64)},
	{27	,(int)(1.00*16), (int)(1.00*64)},
	{28	,(int)(1.00*16), (int)(1.00*64)},
	{29	,(int)(1.00*16), (int)(1.00*64)},
	{30	,(int)(1.00*16), (int)(1.00*64)},
	{31	,(int)(1.00*16), (int)(1.00*64)},
	{32	,(int)(1.00*16), (int)(1.00*64)},
	{33	,(int)(1.00*16), (int)(1.00*64)},
	{34	,(int)(1.00*16), (int)(1.00*64)},	//40
	{35	,(int)(1.00*16), (int)(1.00*64)},
	{36	,(int)(1.00*16), (int)(1.00*64)},
	{38	,(int)(1.00*16), (int)(1.00*64)},
	{39	,(int)(1.00*16), (int)(1.00*64)},
	{40	,(int)(1.00*16), (int)(1.00*64)},
	{42	,(int)(1.00*16), (int)(1.00*64)},
	{43	,(int)(1.00*16), (int)(1.00*64)},
	{45	,(int)(1.00*16), (int)(1.00*64)},
	{46	,(int)(1.00*16), (int)(1.00*64)},
	{48	,(int)(1.00*16), (int)(1.00*64)},	//50
	{50	,(int)(1.00*16), (int)(1.00*64)},
	{51	,(int)(1.00*16), (int)(1.00*64)},
	{53	,(int)(1.00*16), (int)(1.00*64)},
	{55	,(int)(1.00*16), (int)(1.00*64)},
	{57	,(int)(1.00*16), (int)(1.00*64)},
	{59	,(int)(1.00*16), (int)(1.00*64)},
	{61	,(int)(1.00*16), (int)(1.00*64)},
	{63	,(int)(1.00*16), (int)(1.00*64)},
	{66	,(int)(1.00*16), (int)(1.00*64)},
	{68	,(int)(1.00*16), (int)(1.00*64)},	//60
	{70	,(int)(1.00*16), (int)(1.00*64)},
	{73	,(int)(1.00*16), (int)(1.00*64)},
	{75	,(int)(1.00*16), (int)(1.00*64)},
	{78	,(int)(1.00*16), (int)(1.00*64)},
	{81	,(int)(1.00*16), (int)(1.00*64)},
	{84	,(int)(1.00*16), (int)(1.00*64)},
	{87	,(int)(1.00*16), (int)(1.00*64)},
	{90	,(int)(1.00*16), (int)(1.00*64)},
	{93	,(int)(1.00*16), (int)(1.00*64)},
	{96	,(int)(1.00*16), (int)(1.00*64)},	//70
	{99	,(int)(1.00*16), (int)(1.00*64)},
	{103,(int)(1.00*16), (int)(1.00*64)},
	{106,(int)(1.00*16), (int)(1.00*64)},
	{110,(int)(1.00*16), (int)(1.00*64)},
	{114,(int)(1.00*16), (int)(1.00*64)},
	{118,(int)(1.00*16), (int)(1.00*64)},
	{122,(int)(1.00*16), (int)(1.00*64)},
	{127,(int)(1.00*16), (int)(1.00*64)},
	{131,(int)(1.00*16), (int)(1.00*64)},
	{136,(int)(1.00*16), (int)(1.00*64)},	//80
	{141,(int)(1.00*16), (int)(1.00*64)},
	{145,(int)(1.00*16), (int)(1.00*64)},
	{151,(int)(1.00*16), (int)(1.00*64)},
	{156,(int)(1.00*16), (int)(1.00*64)},
	{161,(int)(1.00*16), (int)(1.00*64)},
	{167,(int)(1.00*16), (int)(1.00*64)},
	{173,(int)(1.00*16), (int)(1.00*64)},
	{179,(int)(1.00*16), (int)(1.00*64)},
	{185,(int)(1.00*16), (int)(1.00*64)},
	{192,(int)(1.00*16), (int)(1.00*64)},	//90
	{199,(int)(1.00*16), (int)(1.00*64)},
	{206,(int)(1.00*16), (int)(1.00*64)},
	{213,(int)(1.00*16), (int)(1.00*64)},
	{213,(int)(1.04*16), (int)(1.00*64)},
	{213,(int)(1.07*16), (int)(1.00*64)},
	{213,(int)(1.11*16), (int)(1.00*64)},
	{213,(int)(1.15*16), (int)(1.00*64)},
	{213,(int)(1.19*16), (int)(1.00*64)},
	{213,(int)(1.23*16), (int)(1.00*64)},
	{213,(int)(1.27*16), (int)(1.00*64)},	//100
	{213,(int)(1.32*16), (int)(1.00*64)},
	{213,(int)(1.37*16), (int)(1.00*64)},
	{213,(int)(1.41*16), (int)(1.00*64)},
	{213,(int)(1.46*16), (int)(1.00*64)},
	{213,(int)(1.52*16), (int)(1.00*64)},
	{213,(int)(1.57*16), (int)(1.00*64)},
	{213,(int)(1.62*16), (int)(1.00*64)},
	{213,(int)(1.68*16), (int)(1.00*64)},
	{213,(int)(1.74*16), (int)(1.00*64)},
	{213,(int)(1.80*16), (int)(1.00*64)},	//110
	{213,(int)(1.87*16), (int)(1.00*64)},
	{213,(int)(1.93*16), (int)(1.00*64)},
	{427,(int)(1.00*16), (int)(1.00*64)},
	{427,(int)(1.04*16), (int)(1.00*64)},
	{427,(int)(1.07*16), (int)(1.00*64)},
	{427,(int)(1.11*16), (int)(1.00*64)},
	{427,(int)(1.15*16), (int)(1.00*64)},
	{427,(int)(1.19*16), (int)(1.00*64)},
	{427,(int)(1.23*16), (int)(1.00*64)},
	{427,(int)(1.27*16), (int)(1.00*64)},	//120
	{427,(int)(1.32*16), (int)(1.00*64)},
	{427,(int)(1.37*16), (int)(1.00*64)},
	{427,(int)(1.41*16), (int)(1.00*64)},
	{427,(int)(1.46*16), (int)(1.00*64)},
	{427,(int)(1.52*16), (int)(1.00*64)},
	{427,(int)(1.57*16), (int)(1.00*64)},
	{427,(int)(1.62*16), (int)(1.00*64)},
	{427,(int)(1.68*16), (int)(1.00*64)},
	{427,(int)(1.74*16), (int)(1.00*64)},
	{427,(int)(1.80*16), (int)(1.00*64)},	//130
	{427,(int)(1.87*16), (int)(1.00*64)},
	{427,(int)(1.93*16), (int)(1.00*64)},
	{640,(int)(1.32*16), (int)(1.00*64)},
	{640,(int)(1.37*16), (int)(1.00*64)},
	{640,(int)(1.41*16), (int)(1.00*64)},
	{640,(int)(1.46*16), (int)(1.00*64)},
	{640,(int)(1.52*16), (int)(1.00*64)},
	{640,(int)(1.57*16), (int)(1.00*64)},
	{640,(int)(1.62*16), (int)(1.00*64)},
	{640,(int)(1.68*16), (int)(1.00*64)},	//140
	{640,(int)(1.74*16), (int)(1.00*64)},
	{640,(int)(1.80*16), (int)(1.00*64)},
	{853,(int)(1.37*16), (int)(1.00*64)},
	{853,(int)(1.41*16), (int)(1.00*64)},
	{853,(int)(1.46*16), (int)(1.00*64)},
	{853,(int)(1.52*16), (int)(1.00*64)},
	{853,(int)(1.57*16), (int)(1.00*64)},
	{853,(int)(1.62*16), (int)(1.00*64)},
	{853,(int)(1.68*16), (int)(1.00*64)},
	{853,(int)(1.74*16), (int)(1.00*64)},	//150
	{853,(int)(1.80*16), (int)(1.00*64)},
	{853,(int)(1.87*16), (int)(1.00*64)},
	{853,(int)(1.93*16), (int)(1.00*64)},
	{853,(int)(2.00*16), (int)(1.00*64)},
	{853,(int)(2.07*16), (int)(1.00*64)},
	{853,(int)(2.14*16), (int)(1.00*64)},
	{853,(int)(2.22*16), (int)(1.00*64)},
	{853,(int)(2.30*16), (int)(1.00*64)},
	{853,(int)(2.38*16), (int)(1.00*64)},
	{853,(int)(2.46*16), (int)(1.00*64)},	//160
	{853,(int)(2.55*16), (int)(1.00*64)},
	{853,(int)(2.64*16), (int)(1.00*64)},
	{853,(int)(2.73*16), (int)(1.00*64)},
	{853,(int)(2.83*16), (int)(1.00*64)},
	{853,(int)(2.93*16), (int)(1.00*64)},
	{853,(int)(3.03*16), (int)(1.00*64)},
	{853,(int)(3.14*16), (int)(1.00*64)},
	{853,(int)(3.25*16), (int)(1.00*64)},
	{853,(int)(3.36*16), (int)(1.00*64)},
	{853,(int)(3.48*16), (int)(1.00*64)},	//170
	{853,(int)(3.61*16), (int)(1.00*64)},
	{853,(int)(3.73*16), (int)(1.00*64)},
	{853,(int)(3.86*16), (int)(1.00*64)},
	{853,(int)(4.00*16), (int)(1.00*64)},
	{853,(int)(4.14*16), (int)(1.00*64)},
	{853,(int)(4.29*16), (int)(1.00*64)},
	{853,(int)(4.44*16), (int)(1.00*64)},
	{853,(int)(4.59*16), (int)(1.00*64)},
	{853,(int)(4.76*16), (int)(1.00*64)},
	{853,(int)(4.92*16), (int)(1.00*64)},	//180
	{853,(int)(5.10*16), (int)(1.00*64)},
	{853,(int)(5.28*16), (int)(1.00*64)},
	{853,(int)(5.46*16), (int)(1.00*64)},
	{853,(int)(5.66*16), (int)(1.00*64)},
	{853,(int)(5.86*16), (int)(1.00*64)},
	{853,(int)(6.06*16), (int)(1.00*64)},
	{853,(int)(6.28*16), (int)(1.00*64)},
	{853,(int)(6.50*16), (int)(1.00*64)},
	{853,(int)(6.73*16), (int)(1.00*64)},
	{853,(int)(6.96*16), (int)(1.00*64)},	//190
	{853,(int)(7.21*16), (int)(1.00*64)},
	{853,(int)(7.46*16), (int)(1.00*64)},
	{853,(int)(7.73*16), (int)(1.00*64)},
	{853,(int)(8.00*16), (int)(1.00*64)},
	{853,(int)(8.28*16), (int)(1.00*64)},
	{853,(int)(8.57*16), (int)(1.00*64)},
	{853,(int)(8.88*16), (int)(1.00*64)},
	{853,(int)(9.19*16), (int)(1.00*64)},
	{853,(int)(9.51*16), (int)(1.00*64)},
	{853,(int)(9.85*16), (int)(1.00*64)},	//200
	{853,(int)(10.20*16),(int)(1.00*64)},
	{853,(int)(10.56*16),(int)(1.00*64)},
	{853,(int)(10.93*16),(int)(1.00*64)},
	{853,(int)(11.31*16),(int)(1.00*64)},
	{853,(int)(11.71*16),(int)(1.00*64)},
	{853,(int)(12.13*16),(int)(1.00*64)},
	{853,(int)(12.55*16),(int)(1.00*64)},
	{853,(int)(13.00*16),(int)(1.00*64)},
	{853,(int)(13.45*16),(int)(1.00*64)},
	{853,(int)(13.93*16),(int)(1.00*64)},	//210
	{853,(int)(14.42*16),(int)(1.00*64)},
	{853,(int)(14.93*16),(int)(1.00*64)},
	{853,(int)(15.45*16),(int)(1.00*64)},
	{853,(int)(16.00*16),(int)(1.00*64)},	//214
};

////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION IMPLEMENTATION
////////////////////////////////////////////////////////////////////////////////////////////////////////

static INT32S h22_sccb_open(void)
{
#if SCCB_MODE == SCCB_GPIO
	h22_handle = drv_l2_sccb_open_ext(&h22_cdsp_mipi_sccb_config);
	if(h22_handle == 0)
	{
		DBG_PRINT("Sccb open fail.\r\n");
		return STATUS_FAIL;
	}
#elif SCCB_MODE == SCCB_HW_I2C
	drv_l1_i2c_init(I2C_DEVICE_NUM);
	h22_handle.devNumber = I2C_DEVICE_NUM;
	h22_handle.slaveAddr = H22_ID;
	h22_handle.clkRate = 100;
#endif
	return STATUS_OK;
}

static void h22_sccb_close(void)
{
#if SCCB_MODE == SCCB_GPIO
	if(h22_handle) {
		drv_l2_sccb_close(h22_handle);
		h22_handle = NULL;
	}
#elif SCCB_MODE == SCCB_HW_I2C
	drv_l1_i2c_uninit(I2C_DEVICE_NUM);
	h22_handle.slaveAddr = 0;
	h22_handle.clkRate = 0;
#endif
}

static INT32S h22_sccb_write(INT16U reg, INT8U value)
{
#if SCCB_MODE == SCCB_GPIO
	return drv_l2_sccb_write(h22_handle, reg, value);

#elif SCCB_MODE == SCCB_HW_I2C

	return drv_l1_reg_1byte_data_1byte_write(&h22_handle,reg,value);
#endif
}


static INT32S h22_sccb_read(INT16U reg, INT8U *value)
{
#if SCCB_MODE == SCCB_GPIO
	INT16U data;

	if(drv_l2_sccb_read(h22_handle, reg, &data) >= 0) {
		*value = (INT8U)data;
		return STATUS_OK;
	} else {
		*value = 0xFF;
		DBG_PRINT("i2C read fail!\n");
		return STATUS_FAIL;
	}
#elif SCCB_MODE == SCCB_HW_I2C

	return drv_l1_reg_1byte_data_1byte_read(&h22_handle,reg,value);
#endif
}

static INT32S h22_sccb_write_table(regval8_t *pTable)
{
	while(1)
	{
		if(pTable->reg_num == 0xFF && pTable->value == 0xFF)
		{
			break;
		}

		//DBG_PRINT("0x%02x, 0x%02x\r\n", pTable->reg_num, pTable->value);
		if(h22_sccb_write(pTable->reg_num, pTable->value) < 0)
		{
			DBG_PRINT("sccb write fail.\r\n");
			continue;
		}
		pTable++;
	}
	return STATUS_OK;
}

static INT32S h22_sccb_read_table(regval8_t *pTable)
{
	INT8U Rdata;
	while(1) {
		if(pTable->reg_num == 0x00 && pTable->value == 0x00) {
			break;
		}

		if(h22_sccb_read(pTable->reg_num, &Rdata) < 0) {
			DBG_PRINT("sccb read fail.\r\n");
			continue;
		}
		DBG_PRINT("0x%02x, 0x%02x\r\n", pTable->reg_num, Rdata);
		pTable++;
	}
	return STATUS_OK;
}

/*****************************************************************************************
+++++++++++++++++AEC/AGC
*****************************************************************************************/
static int h22_cvt_agc_gain(int agc_gain)
{

	INT32U h22_agc_gain, i;
	INT32U pow2,set_agc;

	pow2 = 0;
	i = 5;
	do {
		if(agc_gain <= 0x1f)
			break;

		agc_gain >>= 1;
		pow2++;

		i--;
	} while(i != 0);

	agc_gain -= 0x10;

	if(agc_gain < 0) agc_gain = 0;

	switch(pow2)
	{
		case 0:
			set_agc = 0;
		break;

		case 1:
			set_agc	= 1;
		break;

		case 2:
			set_agc	= 3;
		break;

		case 3:
			set_agc = 7;
		break;

		default:
			set_agc	= 0;
		break;
	}

	h22_agc_gain = (set_agc << 4) + agc_gain;

	return h22_agc_gain;
}

#if 0
static int h22_set_xfps_exposure_time(sensor_exposure_t *si)
{
	unsigned char t1, t2;
	int idx, temp, ret;

	//DBG_PRINT("%s:%d\n", __FUNCTION__, __LINE__);
	si->sensor_ev_idx += si->ae_ev_step;
	if(si->sensor_ev_idx >= si->max_ev_idx) si->sensor_ev_idx = si->max_ev_idx;
	if(si->sensor_ev_idx < 0) si->sensor_ev_idx = 0;
#if ENABLE_SAVE_SENSOR_RAW_DATA
	idx = (g_raw_mode_idx < 0) ? si->sensor_ev_idx * 3 : g_raw_mode_idx * 3;
	DBG_PRINT("%s:%d %d\n", __FUNCTION__, __LINE__, g_raw_mode_idx);
#else
	idx = si->sensor_ev_idx * 3;
#endif
	si ->time = p_expTime_table[idx];
	si ->analog_gain = p_expTime_table[idx+1];
	si ->digital_gain = p_expTime_table[idx+2];
	DBG_PRINT("[EV=%d, offset=%d]: time = 0x%x, analog gain =0x%x\r\n", si->sensor_ev_idx, si->ae_ev_step, si->time, si->analog_gain);

	if (ae_flag == 0)
	{
		// exposure time
		if(si ->time != pre_sensor_time)
		{
			pre_sensor_time = si->time;
			temp = si->time;

			t1 = (temp & 0xff);
			t2 = (temp >> 8) & 0x00ff;

			ret = h22_sccb_write(0x01, t1);
			if(ret < 0) return ret;
			ret = h22_sccb_write(0x02, t2);

			if(ret < 0) {
				DBG_PRINT("ERR: write sensor time = 0x%x!!!\r\n", temp);
				return ret;
			}
		}
		ae_flag = 1;
	}

	if(ae_flag == 1)
	{	//Gain
		if(si ->analog_gain != pre_sensor_a_gain)
		{
			pre_sensor_a_gain = si->analog_gain;

			temp = si->analog_gain;
			temp = h22_cvt_agc_gain(temp);
			t1 = temp & 0x007f;
			ret = h22_sccb_write(0x00, t1);
			if(ret < 0) {
				DBG_PRINT("ERR: write sensor gain = 0x%x, 0x%x, 0x%x !!!\r\n", t1, temp, si->analog_gain);
				return ret;
			}
		}
		ae_flag = 0;
	}

	return 0;
}
#else   //Group Write
static int h22_set_xfps_exposure_time(sensor_exposure_t *si)
{
	unsigned char t1, t2;
	int idx, temp, ret;
	INT8U iso_x=1;

	//DBG_PRINT("%s:%d\n", __FUNCTION__, __LINE__);
	/*get iso val*/
	iso_x = (drv_l2_CdspGetIso() & 0xF);
	if (iso_x <= 0) iso_x = 1;

	si->sensor_ev_idx += si->ae_ev_step;
	if(si->sensor_ev_idx >= si->max_ev_idx) si->sensor_ev_idx = si->max_ev_idx;
	if(si->sensor_ev_idx < 0) si->sensor_ev_idx = 0;
#if ENABLE_SAVE_SENSOR_RAW_DATA
	idx = (g_raw_mode_idx < 0) ? si->sensor_ev_idx * 3 : g_raw_mode_idx * 3;
	DBG_PRINT("%s:%d %d\n", __FUNCTION__, __LINE__, g_raw_mode_idx);
#else
	idx = si->sensor_ev_idx * 3;
#endif
	si ->time = p_expTime_table[idx];
	si ->analog_gain = p_expTime_table[idx+1];
	//iso set
	si ->analog_gain = (si ->analog_gain * iso_x);
	si ->digital_gain = p_expTime_table[idx+2];
//ae debug
#if 0
	DBG_PRINT("[EV=%d, offset=%d]: time = %d, analog gain =0x%x\r\n", si->sensor_ev_idx, si->ae_ev_step, si->time, si->analog_gain);
#endif
	// exposure time
	if(si ->time != pre_sensor_time)
	{
		pre_sensor_time = si->time;
		temp = si->time;

		t1 = (temp & 0xff);
		t2 = (temp >> 8) & 0x00ff;
		#if 1 //group write
			ret = h22_sccb_write(0xC0, 0x01);
			if(ret < 0) return ret;
			ret = h22_sccb_write(0xC1, t1);
			if(ret < 0) return ret;
			ret = h22_sccb_write(0xC2, 0x02);
			if(ret < 0) return ret;
			ret = h22_sccb_write(0xC3, t2);
		#else
			ret = h22_sccb_write(0x01, t1);
			if(ret < 0) return ret;
			ret = h22_sccb_write(0x02, t2);
		#endif
		if(ret < 0) {
			DBG_PRINT("ERR: write sensor time = 0x%x!!!\r\n", temp);
			return ret;
		}
	}

	//gain
	if(si ->analog_gain != pre_sensor_a_gain)
	{
		// gain
		pre_sensor_a_gain = si->analog_gain;

		temp = si->analog_gain;
		temp = h22_cvt_agc_gain(temp);
		t1 = temp & 0x007f;
		#if 1   //group write
		ret = h22_sccb_write(0xC4, 0x00);
		if(ret < 0) return ret;
		ret = h22_sccb_write(0xC5, t1);
		#else
		ret = h22_sccb_write(0x00, t1);
		#endif
		if(ret < 0)
		{
			DBG_PRINT("ERR: write sensor gain = 0x%x, 0x%x, 0x%x !!!\r\n", t1, temp, si->analog_gain);
			return ret;
		}

	}
	#if 1//group write
		#if SENSOR_FLIP
		ret = h22_sccb_write(0x12, 0x38);   //group write enable
		#else
		ret = h22_sccb_write(0x12, 0x08);   //group write enable
		#endif
		if(ret < 0) {
			DBG_PRINT("ERR: triger group write FAIL!!!\r\n");
			return ret;
		}
	#endif

	return 0;
}
#endif

static void h22_set_ae(int ev_step)
{
	seInfo.ae_ev_step = ev_step;
	h22_set_xfps_exposure_time(&seInfo);
}

void sensor_register_ae_ctrl(INT32U *handle)
{
	*handle = (INT32U)h22_set_ae;
}


void sensor_get_ae_info(sensor_exposure_t *si)
{
	memcpy(si, &seInfo, sizeof(sensor_exposure_t));
}

void sensor_set_max_lum(int max_lum)
{
	seInfo.max_ev_idx = seInfo.total_ev_idx - (128 - max_lum);
}


/*****************************************************************************************
-------------------AEC/AGC
*****************************************************************************************/
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void jxh22_mipi_set_exp_freq(INT32U freq)
{
	if(freq == 50)
	{
		//seInfo.sensor_ev_idx = H22_30FPS_50HZ_INIT_EV_IDX;
		seInfo.ae_ev_step = 0;
		seInfo.daylight_ev_idx= H22_30FPS_50HZ_DAY_EV_IDX;
		seInfo.night_ev_idx= H22_30FPS_50HZ_NIGHT_EV_IDX;
		//seInfo.max_ev_idx = H22_30FPS_50HZ_MAX_EV_IDX;
		seInfo.total_ev_idx = H22_30FPS_50HZ_EXP_TIME_TOTAL;

		p_expTime_table = (int *)h22_mipi_30fps_exp_time_gain_50Hz;

		DBG_PRINT(">>Set frequence 50Hz.\r\n");
	}
	else if(freq == 60)
	{
		//seInfo.sensor_ev_idx = H22_30FPS_60HZ_INIT_EV_IDX;
		seInfo.ae_ev_step = 0;
		seInfo.daylight_ev_idx= H22_30FPS_60HZ_DAY_EV_IDX;
		seInfo.night_ev_idx= H22_30FPS_60HZ_NIGHT_EV_IDX;
		//seInfo.max_ev_idx = H22_30FPS_60HZ_MAX_EV_IDX;
		seInfo.total_ev_idx = H22_30FPS_60HZ_EXP_TIME_TOTAL;

		p_expTime_table = (int *)h22_mipi_30fps_exp_time_gain_60Hz;

		DBG_PRINT(">>Set frequence 60Hz.\r\n");
	}

	if(seInfo.max_ev_idx > seInfo.total_ev_idx) seInfo.max_ev_idx = seInfo.total_ev_idx;
}

void h22_mipi_seinfo_init(void)
{
	seInfo.sensor_ev_idx = H22_30FPS_50HZ_INIT_EV_IDX;
	seInfo.ae_ev_step = 0;
	seInfo.daylight_ev_idx= H22_30FPS_50HZ_DAY_EV_IDX;
	seInfo.night_ev_idx= H22_30FPS_50HZ_NIGHT_EV_IDX;
	seInfo.max_ev_idx = H22_30FPS_50HZ_MAX_EV_IDX;
	seInfo.total_ev_idx = H22_30FPS_50HZ_EXP_TIME_TOTAL;

	p_expTime_table = (int *)h22_mipi_30fps_exp_time_gain_50Hz;

	pre_sensor_time = 1;
	pre_sensor_a_gain = 0x00;

	seInfo.time = 1;
	seInfo.analog_gain = 0x10;
	seInfo.digital_gain = 0x40;

/*****************************************************************************************/
#ifdef MIPI_ISR_TEST
static void mipi_h22_handle(INT32U event)
{
	if(event & MIPI_LANE0_SOT_SYNC_ERR) {
		DBG_PRINT("LANE0_SOT_SYNC_ERR\r\n");
	}

	if(event & MIPI_HD_1BIT_ERR) {
		DBG_PRINT("HD_1BIT_ERR\r\n");
	}

	if(event & MIPI_HD_NBIT_ERR) {
		DBG_PRINT("HD_NBIT_ERR\r\n");
	}

	if(event & MIPI_DATA_CRC_ERR) {
		DBG_PRINT("DATA_CRC_ERR\r\n");
	}

	if(event & MIPI_LANE1_SOT_SYNC_ERR) {
		DBG_PRINT("LANE1_SOT_SYNC_ERR\r\n");
	}

	if(event & MIPI_CCIR_SOF) {
		DBG_PRINT("CCIR_SOF\r\n");
	}
}
#endif

}

static void h22_mipi_sensor_init(void)
{

	// mclk output
	drv_l2_sensor_set_mclkout(MCLK_24M, MASTER_CLOCK_MIPI_ON, MASTER_CLOCK_CSI_KEEP);

	// reguest sccb
	h22_sccb_open();

	// reset sensor
	h22_sccb_write_table((regval8_t *)h22_reset_table);
	OSTimeDly(2);		//wait 2ms

	// init sensor
	h22_sccb_write_table((regval8_t *)h22_init_table);

	//h22_sccb_read_table((regval8_t *)h22_init_table);

	DBG_PRINT("Sensor H22 sensor mipi init completed\r\n");
}

/**
 * @brief   initialization function
 * @param   sensor format parameters
 * @return 	none
 */
//static void h22_cdsp_mipi_init(void)
void h22_cdsp_mipi_init(void)
{
	DBG_PRINT("%s\r\n", __func__);
	//ae init
	h22_mipi_seinfo_init();
	//cdsp init
	drv_l2_cdsp_open();
	// Reset
	#ifdef FRONT_SENSOR_RESET
	gpio_set_port_attribute(FRONT_SENSOR_RESET, ATTRIBUTE_HIGH);
	gpio_init_io(FRONT_SENSOR_RESET, GPIO_OUTPUT);
	gpio_write_io(FRONT_SENSOR_RESET, DATA_HIGH);
	OSTimeDly(10);
	gpio_write_io(FRONT_SENSOR_RESET, DATA_LOW);
	OSTimeDly(20);
	gpio_write_io(FRONT_SENSOR_RESET, DATA_HIGH);
	OSTimeDly(10);
#endif
#if (MIPI_DEV_NO == 1)			/*mipi enable*/
	drv_l1_mipi_init(MIPI_1, ENABLE);
#else
	drv_l1_mipi_init(MIPI_0, ENABLE);
#endif
	DBG_PRINT("Sensor H42 cdsp mipi[%d] init completed\r\n", MIPI_DEV_NO);
}

/**
 * @brief   un-initialization function
 * @param   sensor format parameters
 * @return 	none
 */
static void h22_cdsp_mipi_uninit(void)
{
	DBG_PRINT("%s\r\n", __func__);
	// disable mclk
	drv_l2_sensor_set_mclkout(MCLK_NONE, MASTER_CLOCK_MIPI_OFF, MASTER_CLOCK_CSI_OFF);

	// cdsp disable
	//drv_l2_cdsp_close();
	// mipi disable
	#if (MIPI_DEV_NO == 1)
		drv_l1_mipi_init(MIPI_1, DISABLE);
	#else
		drv_l1_mipi_init(MIPI_0, DISABLE);
	#endif

	// release sccb
	h22_sccb_close();

	/* Turn off LDO 2.8V for CSI sensor */
	//drv_l1_power_ldo_28_ctrl(0, LDO_LDO28_2P8V);
}

/**
 * @brief   stream start function
 * @param   info index
 *
 * @return 	none
 */
void h22_cdsp_mipi_stream_on(INT32U index, INT32U bufA, INT32U bufB)
{
	INT16U target_w, target_h, sensor_w, sensor_h;
	gpCdspFmt_t format;

	// set sensor size
	DBG_PRINT("%s = %d\r\n", __func__, index);
	/*Enable Mclk out*/
	drv_l2_sensor_set_mclkout(MCLK_24M, MASTER_CLOCK_MIPI_ON, MASTER_CLOCK_CSI_KEEP);

    //Enabel mipi clk, set mipi clk
    drv_l2_mipi_ctrl_set_clk(ENABLE, 4);    //u2.added.20151207

	OSTimeDly(3);	//wait 3ms

	/* cdsp clock */
#if MIPI_DEV_NO == 1
	drv_l1_CdspSetClockTree(ENABLE, MIPI1_INPUT, RAW);
#else
	drv_l1_CdspSetClockTree(ENABLE, MIPI_INPUT, RAW);
#endif

	// set cdsp format
	#if MIPI_DEV_NO == 0
	format.image_source = C_CDSP_MIPI;
	#else
	format.image_source = C_CDSP_MIPI1;
	#endif
	format.input_format =  h22_cdsp_mipi_ops.info[index].input_format;
	format.output_format = h22_cdsp_mipi_ops.info[index].output_format;
	target_w = h22_cdsp_mipi_ops.info[index].target_w;
	target_h = h22_cdsp_mipi_ops.info[index].target_h;
	format.hpixel = sensor_w = h22_cdsp_mipi_ops.info[index].sensor_w;
	format.vline = sensor_h = h22_cdsp_mipi_ops.info[index].sensor_h;
	format.hoffset = h22_cdsp_mipi_ops.info[index].hoffset;
	format.voffset = h22_cdsp_mipi_ops.info[index].voffset;
	format.sensor_timing_mode = h22_cdsp_mipi_ops.info[index].interface_mode;
	format.sensor_hsync_mode = h22_cdsp_mipi_ops.info[index].hsync_active;
	format.sensor_vsync_mode = h22_cdsp_mipi_ops.info[index].vsync_active;


	// set mipi format.
	switch(index)
	{
	case 0:
	case 1:
	case 2:
	case 3:
		h22_mipi_cfg.data_from_mmr = MIPI_AUTO_DETECT;
		h22_mipi_cfg.data_type = MIPI_RAW10;
		//h22_mipi_cfg.pixel_clk_sel = 0;
		break;

	default:
		h22_mipi_cfg.data_from_mmr = MIPI_AUTO_DETECT;
		h22_mipi_cfg.data_type = MIPI_RAW10;
	}

	//mipi start
	#if (MIPI_DEV_NO == 1)
		if (drv_l1_mipi_set_parameter(MIPI_1, &h22_mipi_cfg) < 0)
		{
			DBG_PRINT("MIPI1 init fail !!!\r\n");
		}
		#ifdef MIPI_ISR_TEST
		//drv_l1_mipi_isr_register(mipi_h22_handle);
		drv_l1_mipi_set_irq_enable(MIPI_1, ENABLE, MIPI_INT_ALL);
		#endif
	#else
		if (drv_l1_mipi_set_parameter(MIPI_0, &h22_mipi_cfg) < 0)
		{
			DBG_PRINT("MIPI0 init fail !!!\r\n");
		}
		else
		{
			DBG_PRINT("MIPI0 init completed.\r\n");
			#ifdef MIPI_ISR_TEST
			//drv_l1_mipi_isr_register(mipi_h22_handle);
			drv_l1_mipi_set_irq_enable(MIPI_0, ENABLE, MIPI_INT_ALL);
			#endif
		}
	#endif

	//Enable MCLK & Init Sensor
	h22_mipi_sensor_init();

	if(drv_l2_cdsp_set_fmt(&format) < 0)
	{
		DBG_PRINT("cdsp set fmt err!!!\r\n");
	}

	// set scale down
	if((format.hpixel > target_w) || (format.vline > target_h)) {
		drv_l2_cdsp_set_yuv_scale(target_w, target_h);
	}

	// cdsp start
	drv_l2_CdspTableRegister((gpCisCali_t*)&g_cali);
	drv_l2_cdsp_stream_on(ENABLE, bufA, bufB);
	drv_l2_cdsp_enable((gpUserFav_t*)&g_FavTable ,sensor_w, sensor_h, target_w, target_h);



	// reset sensor ev idx
	seInfo.ae_ev_step = 0;
	h22_set_xfps_exposure_time(&seInfo);
	DBG_PRINT("H22 mipi Exposure Time set!!\r\n");
	drv_l1_CdspSetDataSource(MIPI_INPUT);
	DBG_PRINT("H22 cdsp mipi init done!!\r\n");
}

/**
 * @brief   stream stop function
 * @param   none
 * @return 	none
 */
static void h22_cdsp_mipi_stream_off(void)
{
	DBG_PRINT("%s:no function \r\n", __func__);
	//drv_l2_cdsp_stream_off();
}

/**
 * @brief   get info function
 * @param   none
 * @return 	pointer to sensor information data
 */
static drv_l2_sensor_info_t* h22_cdsp_mipi_get_info(INT32U index)
{
	if(index > (MAX_INFO_NUM - 1))
	{
		return NULL;
	} else
	{
		return (drv_l2_sensor_info_t*)&h22_cdsp_mipi_ops.info[index];
	}
}

/*********************************************
*	sensor ops declaration
*********************************************/
const drv_l2_sensor_ops_t h22_cdsp_mipi_ops =
{
	SENSOR_SOURCE_MIPI,
	SENSOR_PATH_CDSP,
	h22_cdsp_mipi_init,
	h22_cdsp_mipi_uninit,
	h22_cdsp_mipi_stream_on,
	h22_cdsp_mipi_stream_off,
	NULL,
	NULL,
	NULL,
	h22_cdsp_mipi_get_info,
	{
		/* 1st info */
		{
			MASTER_CLOCK_24MHZ,			/* MCLK */
			V4L2_PIX_FMT_SGRBG10,		/* input format */
			V4L2_PIX_FMT_YUYV,			/* output format */
			30,							/* FPS in sensor */
			H22_OUT_WIDTH,				/* target width */
			H22_OUT_HEIGHT,				/* target height */
			H22_WIDTH,					/* sensor width */
			H22_HEIGHT,					/* sensor height */
			0,							/* sensor h offset */
			0,							/* sensor v offset */
			MODE_CCIR_601,				/* input interface */
			MODE_NONE_INTERLACE,		/* interlace mode */
			MODE_ACTIVE_HIGH,			/* hsync pin active level */
			MODE_ACTIVE_HIGH,			/* vsync pin active level */
		}
	}
};
#endif //(defined _SENSOR_H22_CDSP_MIPI) && (_SENSOR_H22_CDSP_MIPI == 1)
